package com.zhangfb95.crosschain.server.controller;

import com.zhangfb95.crosschain.infra.exception.BusinessException;
import com.zhangfb95.crosschain.infra.model.Result;
import com.zhangfb95.crosschain.infra.util.UuidUtil;
import com.zhangfb95.crosschain.protocol.rpc.RequestHeaderConstants;
import com.zhangfb95.crosschain.server.infra.data.converter.AesNamed;
import com.zhangfb95.crosschain.server.infra.data.converter.UserConverter;
import com.zhangfb95.crosschain.server.infra.model.controller.request.rpcuser.RpcUserAddReq;
import com.zhangfb95.crosschain.server.infra.model.controller.request.rpcuser.RpcUserLoginReq;
import com.zhangfb95.crosschain.server.infra.model.controller.request.rpcuser.RpcUserUpdatePasswordReq;
import com.zhangfb95.crosschain.server.infra.model.controller.request.rpcuser.RpcUserUpdateSecretReq;
import com.zhangfb95.crosschain.server.infra.model.controller.request.rpcuser.RpcUserUpdateUsernameReq;
import com.zhangfb95.crosschain.server.infra.model.controller.response.rpcuser.RpcUserLoginRes;
import com.zhangfb95.crosschain.server.infra.model.mapper.entity.User;
import com.zhangfb95.crosschain.server.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;

/**
 * @author zhangfubing
 * @since 2023/10/19
 */
@RequestMapping("/rpc/user")
@RestController
public class RpcUserController {

    @Autowired
    private UserService userService;

    @PostMapping("/add")
    public Result<Void> add(@RequestBody @Validated RpcUserAddReq req) {
        User user = UserConverter.INSTANCE.convert(req);
        user.setSecret(UuidUtil.uuid());
        userService.add(user);
        return Result.ok();
    }

    @PostMapping("/updateUsername")
    public Result<Void> updateUsername(@RequestHeader(RequestHeaderConstants.USER_ID) String userId,
                                       @RequestBody @Validated RpcUserUpdateUsernameReq req) {
        userService.updateUsername(Long.valueOf(userId), req.getUsername());
        return Result.ok();
    }

    @PostMapping("/updatePassword")
    public Result<Void> updatePassword(@RequestHeader(RequestHeaderConstants.USER_ID) String userId,
                                       @RequestBody @Validated RpcUserUpdatePasswordReq req) {
        userService.updatePassword(Long.valueOf(userId), new AesNamed().encryptPassword(req.getDecryptedPassword()));
        return Result.ok();
    }

    @PostMapping("/updateSecret")
    public Result<Void> updateSecret(@RequestHeader(RequestHeaderConstants.USER_ID) String userId,
                                     @RequestBody @Validated RpcUserUpdateSecretReq req) {
        userService.updateSecret(Long.valueOf(userId), req.getSecret());
        return Result.ok();
    }

    @PostMapping("/login")
    public Result<RpcUserLoginRes> login(@RequestBody @Validated RpcUserLoginReq req) {
        User user = userService.getUserByUsername(req.getUsername());
        if (user == null) {
            throw new BusinessException("user not exist");
        }

        String password = new AesNamed().encryptPassword(req.getDecryptedPassword());
        if (!Objects.equals(password, user.getPassword())) {
            throw new BusinessException("password not right");
        }

        return Result.ok(new RpcUserLoginRes().setId(user.getId()).setSecret(user.getSecret()));
    }
}
